#include "DrawPixels.h"
#include <iostream>

using namespace std;

DrawPixels::DrawPixels(void)
{
	/* Initialize the SDL library */
    if(SDL_Init(SDL_INIT_VIDEO) < 0)
	{
        cerr << "Couldn't initialize SDL: %s\n" << SDL_GetError() << endl;
    }

	/*
     * Initialize the display in a 640x480 8-bit palettized mode,
     * requesting a software surface
     */
    screen = SDL_SetVideoMode(320, 240, 8, SDL_SWSURFACE);
    if (screen == NULL)
	{
        cerr << "Couldn't set 320x240x8 video mode: %s\n" << SDL_GetError() << endl;
    }
}

DrawPixels::~DrawPixels(void)
{
	SDL_FreeSurface(screen);
	SDL_Quit();
}

void DrawPixels::run(void)
{
	Uint32 yellow = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);

	if (SDL_MUSTLOCK(screen))
	{
        if (SDL_LockSurface(screen) < 0)
		{
            cerr << "Can't lock screen: %s\n" << SDL_GetError() << endl;
            return;
        }
    }

	for (int i = 0; i < screen->w; i=i+10)
	{
		for (int j = 0; j < screen->h; j=j+10)
		{
			this->putPixel(screen, i, j, yellow);
		}
	}

	if (SDL_MUSTLOCK(screen))
	{
        SDL_UnlockSurface(screen);
    }
    /* Update the entire display */
    SDL_UpdateRect(screen, 0, 0, 0, 0);
	SDLSample::handleEvents();
}

/*
 * Set the pixel at (x, y) to the given value
 * NOTE: The surface must be locked before calling this!
 */
void DrawPixels::putPixel(SDL_Surface* surface, int x, int y, Uint32 pixel)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to set */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        *p = pixel;
        break;

    case 2:
        *(Uint16 *)p = pixel;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
            p[0] = (pixel >> 16) & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = pixel & 0xff;
        } else {
            p[0] = pixel & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = (pixel >> 16) & 0xff;
        }
        break;

    case 4:
        *(Uint32 *)p = pixel;
        break;
    }
}
